<template>
  <div style="height: 100%" class="tree-panel-outer">
    <div class="tree-bar">
      <div>
        <Button size="small" class="top-btn" @click="expandTree" title="展开">展开</Button>
      </div>
      <div>
        <Button size="small" class="top-btn" @click="foldTree" title="收起">收起</Button>
      </div>
      <div style="flex-grow: 1"></div>
      <div v-if="curNode && attachPoint && !validateCfg && !curNode.forkArrayOuter">
        <Button size="small" class="top-btn" @click="growSubComp" title="初始化子组件">grow</Button>
      </div>
      <div v-if="curNode && !attachPoint">
        <Button size="small" type="success" class="top-btn last-btn" @click="initNode" title="初始节点">初始</Button>
      </div>
      <div v-if="curNode && attachPoint && curNode.forkArrayOuter">
        <Button size="small" type="success" class="top-btn" @click="addDimDone" title="添加节点">添加</Button>
      </div>
      <div v-if="curNode && attachPoint && nodeName !== schemaId" title="删除节点">
        <Button size="small" type="error" class="top-btn last-btn" @click="deleteNode">删除</Button>
      </div>
    </div>
    <div style class="tree-panel-inner">
      <Tree :data="treeData" :render="renderContent" @on-select-change="selectTreeNode" ref="tableTree"></Tree>
    </div>
  </div>
</template>

<script>
import BaseLib from '../base/BaseLib';
import SchemaParser from './SchemaParser';
import SchemaConst from './common/SchemaConst';
import SchemaFunc from './common/SchemaFunc';

export default {
  name: 'TreeExplore',
  data() {
    return {
      treeData: [],
      curNode: null,

      attachPoint: null,

      // 为空节点初始化用
      parentPoint: null,
      nodeName: null,
      schemaBlock: null,
      nodeTypeObj: {},
    };
  },
  props: {
    schemaId: {
      type: String,
    },
    metaStoreObj: {
      type: Object,
    },
  },
  computed: {
    validateCfg() {
      const retValue = SchemaFunc.checkBlockAvailable(this.schemaBlock, this.attachPoint);
      return retValue;
    },
  },
  methods: {
    expandTree() {
      this.foldNode(this.treeData[0], true);
    },

    foldTree() {
      this.foldNode(this.treeData[0], false);
    },

    foldNode(curNode, type) {
      curNode.expand = type;
      curNode.children.forEach(item => {
        this.foldNode(item, type);
      });
    },

    initNode() {
      // todo 根据类型初始化数据
      if (this.curNode && this.curNode.forkArrayOuter) {
        this.$set(this.parentPoint, this.nodeName, []);
      } else {
        this.$set(this.parentPoint, this.nodeName, {});
      }
      this.initTreeData();
    },

    deleteNode() {
      if (this.curNode && this.curNode.forkArrayInner) {
        this.parentPoint.splice(this.nodeName, 1);
        // 当前节点删除，选中根节点
        if (this.treeData.length > 0) {
          const nodeKey = this.treeData[0].nodeKey;
          this.$refs.tableTree.handleSelect(nodeKey);
        }
      } else {
        this.parentPoint[this.nodeName] = undefined;
      }
      this.initTreeData();
    },

    addDimDone() {
      // 默认内部类型为对象
      let tmpCfg = {};
      if (this.schemaBlock.$id) {
        const schemaName = this.schemaBlock.$id.split('.')[0];
        tmpCfg = SchemaConst.getDemoCfg(schemaName);
      } else if (this.curNode.nodeName) {
        tmpCfg = SchemaConst.getDemoCfg(this.curNode.nodeName);
      }
      this.attachPoint.push(tmpCfg);
      this.initTreeData();
    },

    growSubComp() {
      const attachPoint = this.attachPoint;
      const schemaBlock = this.schemaBlock;
      SchemaFunc.fillSubCfg(schemaBlock, attachPoint);
      this.initTreeData();
    },
    //--------------------------------
    sortUp(index, callback) {
      const tmpObj = this.attachPoint[index - 1];
      this.attachPoint[index - 1] = this.attachPoint[index];
      this.attachPoint[index] = tmpObj;
      this.initTreeData();
      callback && callback();
    },
    sortDown(index, callback) {
      const tmpObj = this.attachPoint[index + 1];
      this.attachPoint[index + 1] = this.attachPoint[index];
      this.attachPoint[index] = tmpObj;
      this.initTreeData();
      callback && callback();
    },
    copyDim(index, callback) {
      const newObj = BaseLib.cloneDeep(this.attachPoint[index]);
      this.attachPoint.push(newObj);
      this.initTreeData();
      callback && callback();
    },
    deleteDim(index, callback) {
      this.attachPoint.splice(index, 1);
      this.initTreeData();
      callback && callback();
    },
    //--------------------------------
    changeDynForm(pModelKey) {
      if (pModelKey.startsWith('$_')) {
        // 刷新树
        this.initTreeData();
      }
    },

    //--------------------------------
    clearSelect() {
      this.curNode = null;
      this.attachPoint = null;
    },

    selectTreeNode(chooseList) {
      if (chooseList.length === 0) {
        this.curNode = null;
        this.attachPoint = null;
        return;
      }
      this.curNode = chooseList[0];
      const tmpNode = chooseList[0];

      this.parentPoint = tmpNode.parentPoint;
      this.nodeName = tmpNode.nodeName;
      this.attachPoint = tmpNode.attachPoint;
      this.schemaBlock = tmpNode.schemaBlock;
      this.nodeTypeObj = tmpNode.nodeTypeObj;

      this.$emit('select-tree-node', tmpNode);
    },

    initTreeData() {
      // 包装json数据
      const rootMeta = {
        [this.schemaId]: this.metaStoreObj,
      };
      // 包装schema
      const rootSchema = {
        properties: {
          [this.schemaId]: {
            $ref: this.schemaId + '.json',
          },
        },
      };
      // 解析包装后的根节点
      const tmpRoot = SchemaParser.parseNode(rootMeta, rootSchema, rootSchema);
      this.treeData = tmpRoot;

      // 重新选中当前节点
      setTimeout(() => {
        if (this.curNode) {
          this.$refs.tableTree.handleSelect(this.curNode.nodeKey);
        } else if (this.treeData.length > 0) {
          const nodeKey = this.treeData[0].nodeKey;
          this.$refs.tableTree.handleSelect(nodeKey);
        }
      });
    },

    // renderContent(h, { root, node, data })
    renderContent(h, { data }) {
      return h(
        'span',
        {
          style: {
            display: 'inline-block',
            width: '100%',
          },
        },
        [
          h(
            'span',
            {
              attrs: {
                title: data.description,
              },
              class: [
                'ivu-tree-title',
                data.selected ? 'ivu-tree-title-selected' : '',
                data.attachPoint ? '' : 'node-is-null',
                data.required && !data.attachPoint ? 'node-is-required' : '',
              ],
              on: {
                click: () => {
                  this.$refs.tableTree.handleSelect(data.nodeKey);
                },
              },
            },
            [
              h('Icon', {
                props: {
                  type: data.nodeIcon,
                },
                style: {
                  marginRight: '8px',
                },
              }),
              h('span', data.title),
            ]
          ),
        ]
      );
    },
  },
  mounted() {},
};
</script>

<style scoped>
.tree-bar {
  display: flex;
  height: 32px;
  line-height: 36px;
  background-color: #ffffff;
  padding: 0 16px;
}

.top-btn {
  width: 40px;
  margin-right: 8px;
}

.last-btn {
  margin-right: 0;
}

/* ==== */

.tree-panel-inner {
  background-color: #ffffff;
  overflow-y: auto;
  height: calc(100% - 32px);
}

.tree-panel-inner /deep/ .ivu-tree ul {
  font-size: 14px;
}

.tree-panel-inner /deep/ .node-is-null {
  color: #bbbbbb;
}

.tree-panel-inner /deep/ .node-is-required {
  color: #ff9900;
}
</style>
